# 手机相关操作

import time
from uiautomator2 import Device
from PIL import Image
from zz import zz_code, zz_str, zz_log, zz_img, zz_return
import traceback
import os
import glob

log = zz_log.of()

# 防卡死用
ka_arr = [{"msg": "", "count": 0}, {"msg": "", "count": 0}]


def ka_init():
    """
    防卡值初始化
    """
    global ka_arr
    ka_arr = [{"msg": "", "count": 0}, {"msg": "", "count": 0}]


def r_to_dict(r: zz_return.Return) -> dict:
    """
    return 转 dict
    """
    game_dict = r.data

    del_keys = ['errcode', 'errmsg']
    for k, v in game_dict.items():
        if k.startswith("__"):
            del_keys.append(k)

    for key in del_keys:
        game_dict.pop(key)

    return game_dict


config = None
config_path = zz_code.env("CONFIG_PATH")


def config_path_set(path):
    """
    设置配置路径
    """
    global config_path
    config_path = path
    config_to_return(True)


def config_to_return(get_file=False) -> zz_return.Return:
    """
    配置 转 r
    :return:
    """
    global config
    config_file_path = config_path
    config_delete(config_file_path)

    if config is None or get_file:
        config = ""
        try:
            with open(config_file_path, 'r', encoding='utf-8') as file:
                lines = file.readlines()
                for line in lines:
                    config += line
        except Exception as ex:
            traceback.print_exc()
    return zz_return.parse(config)


def config_get(k):
    """
    获取配置
    :param k:
    """
    r = config_to_return()
    val = r.get_data(k)
    if isinstance(val, str):
        val = val.strip()

    return val


def config_set(k, v):
    """
    保存配置
    :param k:
    :param v:
    """
    global config

    r = config_to_return()
    r.set_data(k, v)
    r.data.pop("errcode")
    r.data.pop("errmsg")
    #
    config = r.to_json()
    file = open(config_path, "w", encoding="utf-8")
    # 写入数据
    file.write(config)
    # 关闭文件
    file.close()


def config_delete(file):
    """
    删除旧日志
    :param threshold_days: 删除n天前文件（修改时间）
    """
    delete_date = zz_code.date_sub_day(zz_code.date_today(), 0)
    files = glob.glob("./*.json")
    for file in files:
        if os.path.isfile(file):
            file_create_date = zz_code.date_from_timestamp(os.path.getmtime(file))
            if file_create_date < delete_date:
                os.remove(file)


class ZZ_Game:
    def __init__(self, device: Device, has_prize=True):
        self.d = device
        self.has_prize = has_prize  # 有奖励
        self.index = 1

    def is_page(self, activity, timeout=2):
        """
        判断是否已进入指定页面
        """
        return self.d.wait_activity(activity, timeout=timeout)

    def play_only_1(self):
        """
        只运行1次
        """
        return False

    def search_click_index(self):
        """
        搜索结果点击下标
        """
        return 0

    def set_index(self, index):
        self.index = index

    def not_prize_handle(self):
        """
        无奖励处理
        """
        if not self.has_prize:
            self.d.sleep(1)
            self.log_msg("无奖励处理")
            return True
        return False

    def get_dou_sum(self) -> int:
        """
        获取豆数量
        """
        self.img_click("./game/img/play_game00.png", 3)

        items = self.d(resourceId='pageIndexContainer').child(className="android.widget.TextView")
        dou_total = 0
        dou = 0
        if len(items) >= 4:
            if items[2].get_text() == '你有':
                dou = int(items[3].get_text())
        if len(items) >= 2:
            dou_total = int(items[1].get_text())
            config_set('__dou_total', dou_total)  # 记录总游戏豆

        self.log_msg(f"游戏豆：{dou}[{dou_total}]")
        return dou

    def get_dou(self):
        self.log_msg("开始领取游戏豆，点击赚玩乐豆")
        log.info("进入游戏中心主页")
        is_page0 = self.d.xpath('//*[@resource-id="pageIndexContainer"]').wait(2)
        if is_page0:
            self.img_click("./game/img/play_game02.png")
            self.d.sleep(1)

        is_page_center = self.d.xpath('//*[@resource-id="task"]').wait(5)
        if not is_page_center:
            self.log_msg("已进入游戏中心主页失败, 请重新运行")
            return False

        if not self.d.xpath('//android.widget.TextView[@text="全部领取"]').wait(3):
            self.log_msg("玩乐豆已领取")
            return False

        self.log_msg("点击领取奖励")
        self.d.xpath('//android.widget.TextView[@text="全部领取"]').click()
        return True

    def set_begin_time(self):
        """
        记录开始时间
        :return:
        """
        r = config_to_return()
        if r.exists('__begin_time'):
            return
        config_set('__begin_time', zz_code.date_tostring())

    def game_count(self):
        """
        已做游戏总数
        """
        game_dict = r_to_dict(config_to_return())
        return len(game_dict)

    def handle(self) -> bool:
        """
        返回运行是否成功
        :return:
        """
        self.set_index(self.game_count() + 1)
        self.log_msg(f"点击进入游戏")
        game_data = config_get(self.get_name())
        handle_begin = zz_code.date_now()
        err_count = 0
        if game_data is not None:
            handle_begin = zz_code.date_from_str(game_data['handle_begin'])
            err_count = game_data['err_count']
        else:
            # 记录游戏开始时间
            config_set(self.get_name(), {
                'state': None,
                'err_count': 0,
                'handle_begin': zz_code.date_tostring(handle_begin),
                'handle_second': 9999,

            })
        self.d.sleep(2)

        try:
            done = self.check_done()
            if done:
                self.log_msg("游戏任务已完成，退出游戏")
                self.d.sleep(1)
                ok = True
            else:
                self.d.sleep(8)
                self.done_close()
                ok = self.handle_main()
                if ok is None:
                    ok = True
        except Exception as ex:
            traceback.print_exc()
            log.error(f"脚本报错，退出游戏：{ex}")
            ok = False
            ka_init()
        finally:
            self.d.sleep(2)
            self.close_game()

        if not ok:
            err_count += 1
        handle_end = zz_code.date_now()
        handle_span = handle_end - handle_begin
        # 记录已执行任务
        config_set(self.get_name(), {
            'state': ok,
            'err_count': err_count,
            'handle_begin': zz_code.date_tostring(handle_begin),
            'handle_second': handle_span.seconds,
        })
        return ok

    def click_bottom(self, rate=0.1):
        """
        点击屏幕底部空白地方
        :param rate: 默认点击位置，底部的10%
        :return:
        """
        w, h = self.d.window_size()
        x = w / 2
        y = h - (h * rate)
        self.d.click(x, y)
        self.log_msg(f"点击底部-({x},{y})")
        self.d.sleep(1.5)

    def click_top(self, rate=0.1):
        """
        点击屏幕顶部空白地方
        :param rate: 默认点击位置，底部的10%
        :return:
        """
        w, h = self.d.window_size()
        x = w / 2
        y = int(h * rate)
        self.d.click(x, y)
        self.log_msg(f"点击顶部-({x},{y})")
        self.d.sleep(1.5)

    def alert_close_by_file(self, dir_path, threshold=0.8, fix_name='alert_', handle_1=False):
        """
        根据文件名处理弹窗关闭
        文件名规则：alert_关闭方式_序号.png
        :param dir_path:
        :param fix_name: 图片名前缀，alert_0_01
        :param threshold: 容错值
        :param handle_1: 只处理1次
        """
        file_list = os.listdir(dir_path)
        alert_list = []
        for file_name in file_list:
            if file_name.startswith(fix_name):
                alert_list.append(file_name)
        if len(alert_list) <= 0:
            self.log_msg("无弹窗图片")
            return
        self.log_msg(f"{len(alert_list)}张弹窗图片")
        while True:
            handle = False
            for file_name in alert_list:
                click_close = int(file_name.split("_")[1])
                file_path = f"{dir_path}/{file_name}"
                handle = self.alert_close(file_path, click_close, 1, threshold)
                if handle_1:
                    handle = False
                if handle:
                    # 弹窗关闭成功会再判断多1次
                    while self.alert_close(file_path, click_close, 1, threshold):
                        pass
                    break
            if handle:
                continue
            break

    def alert_close(self, target_path, click_close=0, timeout=2, threshold=0.8):
        """
        弹窗关闭处理
        :param target_path:
        :param click_close: 0:点击关闭；1：点击底部关闭；2：点击顶关闭
        :param timeout:
        :param threshold: 容错值
        :return:
        """
        r = self.find_img(target_path, timeout, threshold)
        alert_name = target_path.split('/')[-1:][0]
        if r.ok():
            self.d.sleep(1)
            self.log_msg(f"存在活动弹窗，进行关闭-{alert_name}")
            if click_close == 0:
                center_list = r.get_data("center_list")
                self.log_msg(f"关闭方式【点击】，坐标{center_list}")
                for center in center_list:
                    self.log_msg(f"关闭方式【点击】，坐标({center[0]},{center[1]})")
                    self.d.click(center[0], center[1])
                    self.d.sleep(1)
            elif click_close == 1:
                self.click_bottom()
            else:
                self.click_top()
            return True
        else:
            self.log_msg(f"未找到弹窗-{alert_name}")
        self.d.sleep(1.5)
        return False

    def handle_main(self):
        pass

    def click_exists(self, xpath_val, timeout=3) -> bool:
        elem = self.d.xpath(xpath_val)
        return elem.click_exists(timeout)

    def qian(self):
        """
        签到
        :return:
        """
        # 判断是否已签到
        if self.d.xpath('//android.widget.TextView[@text="明天签到可领"]').wait(2):
            self.log_msg("已签到")
            return
        if not self.d.xpath('//android.widget.TextView[@text="签到"]').wait(1):
            self.log_msg("已签到")
            return
        self.log_msg("开始签到")
        self.d.xpath('//android.widget.TextView[@text="签到"]').click()
        self.d.sleep(2)
        self.log_msg("点击奖励翻倍")
        self.d.xpath('//android.widget.Button[@text="奖励翻倍"]').click()
        self.d.sleep(6)
        self.log_msg("进行游戏，等待完成签到")

        self.d.xpath('//*[@text="悬浮球模版"]').wait(5)
        for i in range(25):
            self.swipe_up()
            self.d.sleep(2)
            self.log_msg(f"{i}-继续等待")

        self.log_msg("签到已完成")
        self.close_game()

    def get_name(self):
        return "通用"

    def log_msg(self, msg, do_ka_check=True):
        """
        输出日志，统一格式
        :param msg:
        :param do_ka_check: true检查卡死状态
        """

        log.info(f"{self.get_name()}[{self.index}]---{msg}")

        if do_ka_check:
            if self.ka_status(msg):
                # 保存卡死界面图片
                self.swipe_up()
                img = self.d.screenshot()
                img.save(f"../_tmp/ka_{self.get_name()}_{zz_code.date_tostring(None, '%Y%m%d_%H%M%S')}.png")

                raise ValueError(f"{self.get_name()}[{self.index}]---触发防卡死机制，进行重启")

    def ka_status(self, msg) -> bool:
        """
        卡死状态，重复提示出现15次以上，视为卡死状态
        """
        global ka_arr

        match = False
        for item in ka_arr:
            if msg == item["msg"]:
                match = True
                item["count"] += 1
                break

        if not match:
            # 退一位
            ka_arr[1] = ka_arr[0]
            ka_arr[0] = {"msg": msg, "count": 0}

        ka = False  # 判断是否卡死
        for item in ka_arr:
            if item["count"] >= 10:
                ka = True
                item["count"] = 0  # 重置次数
                break
        return ka

    def find_color(self, x, y, color_arr, tolerance=10) -> bool:
        """
        手机某位置颜色是否匹配
        :param x:
        :param y:
        :param color_arr:
        :param tolerance: 容错值
        """
        img = self.d.screenshot()
        return zz_img.color_eq(img.getpixel((x, y)), color_arr, tolerance)

    def find_img(self, target_path, timeout=10, threshold=0.8, index=0) -> zz_return.Return:
        """
        查询图片位置
        :param target_path: 查询目标图片
        :param timeout: 超时时间
        :param threshold: 容错值
        :return:
        """
        img_target = Image.open(target_path)
        deadline = time.time() + timeout
        while True:
            r = zz_img.find_img(self.d.screenshot(), img_target, threshold, index)
            # log.info(r.to_json())
            if r.ok():
                return r

            if time.time() > deadline:
                return zz_return.of(20029, "未匹配到位置")
            time.sleep(0.5)

    def img_exit(self, target_path, timeout=5, threshold=0.8) -> bool:
        """
        图片是否存在
        :param target_path:
        :param timeout: 等待时间（秒）
        """
        r = self.find_img(target_path, timeout, threshold)
        return r.ok()

    def img_click_if_exists(self, msg, click_path, existe_path, key='center'):
        """
        点击后，判断结果是否正确，否则重新点击
        :param msg:
        :param click_path: 点击图片
        :param existe_path: 点击后，期待出现的图片
        :return:
        """
        self.log_msg(msg)
        self.img_click(click_path, key=key)
        while not self.img_exit(existe_path):
            self.log_msg(f"{msg}-失败，再尝试")
            self.img_click(click_path)

    def img_click_if_exists_xpath(self, msg, click_path, xpath_key):
        """
        点击后，判断结果是否正确，否则重新点击
        :param msg: 描述
        :param click_path: 点击图片
        :param xpath_key: 点击后，期待出现的组件标记
        :return:
        """
        self.log_msg(msg)
        if self.d.xpath(xpath_key).wait(2):
            return
        self.img_click(click_path)
        while not self.d.xpath(xpath_key).wait(2):
            self.log_msg(f"{msg}-失败，再尝试")
            self.img_click(click_path)

    def img_click_if_exists_page(self, msg, click_path, activity):
        """
        点击后，判断结果是否正确，否则重新点击
        :param msg: 描述
        :param click_path: 点击图片
        :param activity: 包路径
        :return:
        """
        self.log_msg(msg)
        self.img_click(click_path)
        while not self.is_page(activity):
            self.log_msg(f"{msg}-失败，再尝试")
            self.img_click(click_path)

    def img_click(self, target_path, timeout=3, click_count=1, threshold=0.8, index=0, key='center') -> bool:
        """
        点击图片，返回成功失败
        :param click_count: 点击次数
        :param timeout: 超时时间
        :param target_path:
        """
        r = self.find_img(target_path, timeout, threshold, index)
        if r.err():
            self.log_msg(f"{target_path.split('/')[-1:][0]}-{r.get_errmsg()}")
            return False
        x, y = r.get_data(key)
        for i in range(click_count):
            self.d.click(x, y)
            self.d.sleep(0.1)
        self.d.sleep(2)
        return True

    def img_click_for(self, msg, target_path, index=0) -> bool:
        """
        点击成功，才会终止
        :param msg: 描述
        :param target_path:
        :param index: 点击第几个图片
        """
        self.log_msg(msg)
        while not self.img_click(target_path, 3, 1, 0.8, index):
            self.log_msg(f"{msg}-失败，继续尝试")
        return True

    def xpath_click(self, xpath):
        """
        根据元素点击
        """
        try:
            if self.d.xpath(xpath).wait(2):
                self.d.xpath(xpath).click(2)
            else:
                return False
        except Exception as ex:
            self.log_msg(f"{ex}")
            return False
        return True

    def click_back(self):
        self.log_msg("后退")
        self.d.press("back")
        self.d.sleep(1.5)

    def fu_check(self, check_count):
        ok = False
        try:
            self.xpath_click('//*[@resource-id="app"]')
            self.d.sleep(1)
            self.xpath_click('//*[@resource-id="app"]')
            self.d.sleep(2)
            if not self.img_exit("./game/img/春节/chou_alert.png", 3):
                raise ValueError("奖励弹窗打开失败")
            self.log_msg("已打开奖励弹窗，开始领取奖励")
            done_count = len(self.d.xpath('//android.widget.TextView[@text="已完成"]').all())
            self.log_msg(f"任务已完成数量：{done_count} <= 检查数量：{check_count}")
            ok = done_count >= check_count
        except Exception as ex:
            # traceback.print_exc()
            self.log_msg(f"检查奖励报错：{ex}")

        self.done_close()
        return ok

    def get_fu(self):
        self.log_msg("领奖励")
        try:
            self.xpath_click('//*[@resource-id="app"]')
            self.d.sleep(1)
            self.xpath_click('//*[@resource-id="app"]')
            self.d.sleep(2)
            if not self.img_exit("./game/img/春节/chou_alert.png", 3):
                raise ValueError("奖励弹窗打开失败")
            self.log_msg("已打开奖励弹窗，开始领取奖励")
            chou_list = self.d.xpath('//android.widget.TextView[@text="抽福卡"]').all()
            index = 0
            for item in chou_list:
                index += 1
                self.log_msg(f"点击领取-{index}")
                item.click()
                self.d.sleep(1)
                self.log_msg("等待领取成功弹窗")
                if not self.img_exit("./game/img/春节/chou_done.png", 3):
                    self.log_msg("奖励未完成")
                    continue
                self.log_msg("点击开心收下")
                self.img_click("./game/img/春节/chou_done.png", 5)
                self.log_msg("点击关闭")
                self.xpath_click('//*[@resource-id="com.alipay.mobile.blessingcard:id/cr_close"]')
                if self.img_exit("./game/img/春节/ca_alert_01.png", 2):
                    self.log_msg("存在安慰弹窗，点击关闭")
                    self.img_click("./game/img/春节/ca_alert_01.png")

                self.d.sleep(3)
            self.done_close()
        except Exception as ex:
            # traceback.print_exc()
            self.log_msg(f"{ex}")
            raise ValueError(ex)
        return True

    def done_close(self):
        """
        弹窗关闭
        """
        self.log_msg("关闭弹窗")
        app = self.d.xpath('//android.webkit.WebView[@text="五福"]').child("//android.widget.TextView").all()
        if len(app) > 1:
            app[1].click()

    def check_done(self, throw=True):
        """
        检查游戏是否已完成
        :return:
        """
        done = False
        if not self.has_prize:
            # 没有奖励，直接返回
            return False

        self.log_msg("检查任务完成状态")
        try:
            self.d.xpath('//*[@resource-id="app"]').click()
            self.d.sleep(1)
            self.d.xpath('//*[@resource-id="app"]').click()
            # self.d.sleep(1)
            if not self.d.xpath('//android.widget.TextView[@text="每日任务"]').wait(3):
                raise ValueError("获取任务完成状态异常")
            item = self.d.xpath('//android.widget.TextView[@text="每日任务"]').get(3)
            if item is None:
                self.log_msg("未找到每日任务")
                return False
            item_next = item.elem.getnext()
            if item_next is None:
                self.log_msg("每日任务，没有下一级")
                return False
            if len(item_next.getchildren()) < 4:
                return False
            done = item_next.getchildren()[3].attrib['text'] != '待完成'
            self.d.sleep(1)

            self.done_close()
        except Exception as ex:
            # traceback.print_exc()
            self.log_msg(f"{ex}")
            raise ValueError("获取任务完成状态异常")

        self.log_msg(f"任务完成状态：{done}")
        self.d.sleep(1.5)
        return done

    def do_task_view(self):
        """
        浏览任务
        :return:
        """
        # ok = self.d.xpath('//android.widget.TextView[@text="商品展示由阿里妈妈提供技术支持"]').wait(5)
        ok = self.img_exit('./game/img/task_main.png', 5)
        if not ok:
            self.log_msg(f"进入浏览页面失败")
            return
        self.log_msg(f"已进入浏览页面，开始浏览30秒")
        while not self.img_exit("./game/img/task_done.png", 2):
            self.swipe_up()
            self.d.sleep(1.5)
            self.swipe_up()
            self.d.sleep(1.5)
            self.swipe_down()
            self.d.sleep(1.5)
            self.swipe_down()
            self.d.sleep(1.5)

            if self.d.xpath('//*[@text="已获得奖励"]').wait(2):
                break

        self.d.xpath('//*[@content-desc="关闭"]').click()
        self.log_msg("退出浏览任务")

    def close_game(self, xy_click=False):
        """
        关闭当前游戏
        :return:
        """
        self.log_msg("点击退出游戏", False)
        if xy_click:
            self.d.click(1110, 195)
        else:
            self.xpath_click('//*[@content-desc="关闭"]')

    def get_task_one(self, names):
        """
        获取1个任务
        :return:
        """
        # 回到游戏中心页面顶部
        self.swipe_down()
        self.swipe_down()
        self.swipe_down()

        r = config_to_return()
        task_one = None
        while task_one is None:
            self.swipe_up()
            task = self.d.xpath('//*[@resource-id="task"]')
            if task is None:
                break
            list_task = task.child("android.view.View").all()
            if len(list_task) <= 0:
                break
            for item in list_task:
                if len(item.elem.getchildren()) <= 2:
                    continue

                task_item = item.elem.getchildren()[1]
                task_item_child = task_item.getchildren()
                if len(task_item_child) < 2:
                    continue

                # 获取游戏名
                game_name = task_item.getchildren()[1].attrib['text']
                game_name = game_name[1:len(game_name)]  # 去掉玩
                log.info(f"游戏：{game_name}")
                game_run = r.get_data(game_name)
                if game_run is not None:
                    game_state = game_run['state']
                    if game_state is not None:
                        if game_state:
                            log.info(f"{game_name}-运行完成")
                        else:
                            log.info(f"{game_name}-运行报错，过滤")
                        continue

                if zz_code.arr_find(names, game_name):
                    task_one = [item, names[game_name]]  # 找到未执行的游戏，跳出循环
                    break
        return task_one

    def screenshot(self):
        """
        获取载图
        :return:
        """
        # 保存 cv2.imwrite('home.jpg', image)
        return self.d.screenshot(format='opencv')

    def swipe_up(self, duration=0.5):
        """
        向上滑半屏
        :return:
        """
        self.log_msg("向上滑半屏")
        w, h = self.d.window_size()
        self.d.swipe(w / 2, h / 2, w / 2, 10, duration)

    def swipe_down(self, duration=0.5):
        """
        向下滑半屏
        :return:
        """
        self.log_msg("向下滑半屏")
        w, h = self.d.window_size()
        self.d.swipe(w / 2, 400, w / 2, h / 2, duration)

    def swipe_right(self, duration=0.5, do_ka_check=True, end_x_rate=0.1):
        """
        向右滑半屏
        :return:
        """
        self.log_msg("向右滑半屏", do_ka_check)
        w, h = self.d.window_size()
        self.d.swipe(w / 2 - (w * 0.1), h / 2, w - (w * end_x_rate), h / 2, duration)

    def swipe_left(self, duration=0.5):
        """
        向左滑半屏
        :return:
        """
        self.log_msg("向左滑半屏")
        w, h = self.d.window_size()
        self.d.swipe(w / 2, h / 2, (w * 0.1), h / 2, duration)

    def open_app(self):
        """
        打开支付宝
        """
        self.log_msg("关闭支付宝")
        self.d.app_stop("com.eg.android.AlipayGphone")
        self.d.sleep(1)
        self.log_msg("打开支付宝")
        self.d.app_start("com.eg.android.AlipayGphone")
        self.d.sleep(1)
        self.log_msg("等待进入支付宝主界面")
        self.d.xpath('//*[@text="游戏中心"]').wait(20)
        self.log_msg("已进入支付宝主界面")

        self.img_click_if_exists('点击我的', "./game/img/my.png", "./game/img/my_main.png")
        # self.d.xpath('//*[@resource-id="com.alipay.android.tablauncher:id/tab_icon"]').wait(3)
        # self.d.xpath('//*[@resource-id="com.alipay.android.tablauncher:id/tab_icon"]').all()[-1].click()
        self.d.sleep(1)
        accountName = self.d.xpath('//*[@resource-id="com.alipay.android.phone.wealth.home:id/name"]').get_text()
        accountId = self.d.xpath('//*[@resource-id="com.alipay.android.phone.wealth.home:id/account"]').get_text()

        self.log_msg(f"{accountId}")
        self.log_msg(f"帐号名称-{accountName}")
        self.log_msg("点击首页")
        self.d.xpath('//*[@resource-id="com.alipay.android.tablauncher:id/tab_icon"]').click()
        config_path_set(f"./game_config_{accountName}.json")
        config_set('__account_id', accountId)

    def open_game_center(self):
        """
        打开游戏中心
        """
        self.log_msg("点击游戏中心")
        self.d.sleep(1)
        self.img_click("./game/img/game_center_index.png", 3)
        # self.d.xpath('//*[@text="游戏中心"]').click()
        self.log_msg("等待打开支付宝->游戏中心")
        wa = self.d.xpath('//*[@text="游戏中心"]').wait(20)
        if not wa:
            self.log_msg("等待超时, 请重新运行")
            return False

        log.info("进入游戏中心主页")
        self.xpath_click('//android.widget.TextView[@text="游戏圈"]')
        if not self.img_exit("./game/img/play_game02.png", 5):
            self.log_msg("进入游戏中心->游戏圈主页失败, 请重新运行")
            return False

        # self.log_msg("点击搜索游戏")
        # self.xpath_click('//android.widget.TextView[@text="搜索小游戏"]')
        # is_page0 = self.d.xpath('//*[@resource-id="pageIndexContainer"]').wait(2)
        # if is_page0:
        #     self.img_click("./game/img/play_game02.png")
        #     self.d.sleep(1)
        #
        # is_page_center = self.d.xpath('//*[@resource-id="task"]').wait(5)
        # if not is_page_center:
        #     log.error("已进入游戏中心主页失败, 请重新运行")
        #     return False
        return True

    def click_if_exists(self, msg, click_xpath, existe_xpath):
        """
        点击后，判断结果是否正确，否则重新点击
        :param msg:
        :param click_xpath: 点击图片
        :param existe_xpath: 点击后，期待出现的图片
        :return:
        """
        self.log_msg(msg)
        if self.d.xpath(existe_xpath).wait(2):
            return
        self.xpath_click(click_xpath)
        while not self.d.xpath(existe_xpath).wait(2):
            self.log_msg(f"{msg}-失败，再尝试")
            self.xpath_click(click_xpath)


def change_account(g: ZZ_Game) -> zz_return.Return:
    """
    切换帐号
    """
    g.log_msg("开始切换帐号，点击我的")
    accounts_done = []
    files = glob.glob("./*.json")
    for file in files:
        r = zz_return.file_to_return(file)
        account_id = r.get_data("__account_id")
        ad = r.get_data("__account_done")
        if ad == 1:
            accounts_done.append(account_id)
    g.log_msg(f"已完成账号：{accounts_done}")
    g.d.sleep(1)
    g.log_msg(f"点击我的")
    g.d.xpath('//*[@resource-id="com.alipay.android.tablauncher:id/tab_icon"]').all()[-1].click()
    g.d.sleep(1)
    g.log_msg("点击设置")
    g.d.xpath('//*[@content-desc="设置"]').click()
    while not g.img_exit("./game/img/login_account.png"):
        g.log_msg(f"点击设置-失败，再尝试")
        g.d.xpath('//*[@content-desc="设置"]').click()
    g.d.sleep(1)
    g.img_click_if_exists('点击登录其他账号', "./game/img/login_account.png", "./game/img/login_account_list.png")

    g.log_msg("获取账号列表")
    if not g.d.xpath('//*[@resource-id="com.alipay.mobile.securitybiz:id/tv_am_item_account"]').wait(10):
        g.log_msg('获取账号列表失败')
        return zz_return.of(2027, "获取账号列表失败")
    items = g.d.xpath('//*[@resource-id="com.alipay.mobile.securitybiz:id/tv_am_item_account"]').all()
    for item in items:
        account_id = item.text
        g.log_msg(f"账号：{account_id}")
        if not zz_str.contains(account_id, '\\*\\*\\*'):
            # 过滤非帐号
            continue

        if zz_code.arr_find(accounts_done, account_id):
            g.log_msg(f'{account_id}：已完成')
            continue

        g.d.sleep(1)
        g.log_msg(f"点击切换: {item.bounds}")
        item.click()
        g.log_msg(f"等待10秒")
        g.d.sleep(10)

        return zz_return.of(0)

    return zz_return.of(2037, "全部帐号已完成")
